﻿using System;
using System.Collections.Generic;
using Microsoft.Practices.ObjectBuilder2;
using Ymatou.Evaluate.Buyer.Model.ApiModel.Request.Operator;
using Ymatou.Evaluate.Buyer.Model.ApiModel.Response.Operator;
using Ymatou.Evaluate.Data.Operator;
using Ymatou.Evaluate.Entity;
using Ymatou.Evaluate.Service.Buyer.Extensions;
using Ymatou.Evaluate.Service.Buyer.Interface;
using System.Linq;
using Ymatou.API.Order.Model.Request.OrderRequest;
using Ymatou.CommonService;
using Ymatou.API.Order.Model.Response.OrderResponse;
using Ymatou.API.Common;
using Newtonsoft.Json;
using Ymatou.Evaluate.Common;
using Ymatou.Counter.Contract;
using Ymatou.ProductQuery.BuyerModel.Request.ListRequest;
using Ymatou.ServiceCenter;
using Ymatou.Evaluate.Data.Query;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Ymatou.Evaluate.Service.Buyer.Implement
{
    internal class BuyerOperatorService : IBuyerOperatorService
    {
        /// <summary>
        /// 初始化评价状态
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <param name="sellerId">买手Id</param>
        /// <param name="buyerId">买家Id</param>
        /// <returns></returns>
        public bool AddEvaluateStatus(int orderId, int sellerId, int buyerId, out string msg)
        {
            var pslist = new List<EvaluateProdStatus>();
            //评价订单状态相关校验和处理
            return AddEvaluateStatus(orderId, sellerId, buyerId, out msg, out pslist);
        }

        /// <summary>
        /// 初始化评价状态
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <param name="sellerId">买手Id</param>
        /// <param name="buyerId">买家Id</param>
        /// <returns></returns>
        public bool AddEvaluateStatus(int orderId, int sellerId, int buyerId, out string msg,
            out List<EvaluateProdStatus> pslist)
        {
            pslist = new List<EvaluateProdStatus>();
            msg = "";
            try
            {
                //查询是否已初始化
                var orderStatusList = EvaluateQueryData.GetOrderStatusByBuyerIdOrderIds(buyerId,
                    new List<int>() { orderId });
                //校验已初始化的订单是否是同一买手
                if (orderStatusList != null && orderStatusList.Any(x => x.SellerId == sellerId))
                {
                    //判断订单是否已评价过
                    if (orderStatusList.FirstOrDefault().Status == EvaluateStatus.Evaluated)
                    {
                        msg = "该订单已评价";
                        return false;
                    }
                    msg = "该订单已处理";
                    return true;
                }
                var orderStatus = new EvaluateOrderStatus();
                var order = GetSellerSingleOrderInfo(orderId, buyerId);
                //校验订单是否是同一买家
                if (order == null || order.BuyerId != sellerId)
                {
                    msg = "该订单不存在";
                    return false;
                }
                orderStatus.BuyerId = buyerId;
                orderStatus.OrderId = orderId;
                orderStatus.SellerId = sellerId;
                orderStatus.Status = EvaluateStatus.Pending;
                if (order.OrderItemList != null && order.OrderItemList.Count > 0)
                {
                    pslist = order.OrderItemList.Select(x => new EvaluateProdStatus
                    {
                        Status = EvaluateStatus.Pending,
                        BuyerId = buyerId,
                        OrderId = orderId,
                        SellerId = sellerId,
                        ProductId = x.ProductId,
                        CatalogId = x.CatalogId
                    }).ToList();

                    return EvaluateOperatorData.AddEvaluateStatus(orderStatus, pslist);
                }
            }
            catch (Exception ex)
            {
                ApplicationLog.Error("初始化评价状态Exception  AddEvaluateStatus", ex);
            }
            return false;
        }

        /// <summary>
        /// 删除评价
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public RemoveEvaluateResponse RemoveEvaluate(RemoveEvaluateRequest request, out string msg)
        {
            var result = new RemoveEvaluateResponse();
            msg = "";
            try
            {
                var product = EvaluateOperatorData.UpdateEvaluateProduct(request.BuyerId, request.ProdEvalId,
                    request.ProductId);
                if (product != null && product.IsDeleted)
                {
                    result.IsSuccess = true;
                    //异步减少评价数Redis
                    new Task(() => SysSetCounterRedis(product)).Start();
                    //异步处理商品评分
                    new Task(() => SysSetProductScore(new List<string>() { product.ProductId })).Start();
                }
                else
                {
                    msg = "评价不存在或者已删除";
                }
            }
            catch (Exception ex)
            {
                ApplicationLog.Error(
                    string.Format("删除评价Exception  RemoveEvaluate：【{0}】",
                        Newtonsoft.Json.JsonConvert.SerializeObject(request)), ex);
            }
            return result;
        }

        /// <summary>
        /// 提交评价
        /// </summary>
        /// <param name="request"></param>
        /// <param name="msg"></param>
        /// <param name="isNeedCounter">是否需要计数</param>
        /// <returns></returns>
        public SubmitEvaluateResponse SubmitEvaluate(SubmitEvaluateRequest request, out string msg,
            bool isNeedCounter = true)
        {
            var result = new SubmitEvaluateResponse();
            msg = "";
            try
            {
                var pslist = new List<EvaluateProdStatus>();
                //评价订单状态相关校验和处理
                var flag = AddEvaluateStatus(request.OrderId, request.SellerId, request.BuyerId, out msg, out pslist);
                if (!flag)
                {
                    if (string.IsNullOrEmpty(msg))
                    {
                        msg = "该订单评价失败";
                    }
                    return result;
                }
                else
                {
                    msg = "";
                }
                //获取商品的评价状态
                if (pslist == null || pslist.Count <= 0)
                    pslist = EvaluateQueryData.GetProdStatusBySellerIdBuyerIdOrderId(request.SellerId, request.BuyerId,
                        request.OrderId);
                if (pslist != null && pslist.Count > 0)
                {
                    if (!CheckProductList(request.ProductsEvaluate, pslist))
                    {
                        msg = "评价的商品和规格与订单不符";
                        return result;
                    }
                }
                //组装评价订单信息
                var order = GetEvaluateOrder(request);
                //组装评价商品信息
                var pList = (from x in request.ProductsEvaluate.AsParallel().WithDegreeOfParallelism(10)
                             select GetEvaluateProductImg(request, x)).ToList();
                //写入数据库
                result.IsSuccess = EvaluateOperatorData.AddEvaluate(order, pList);
                if (result.IsSuccess && isNeedCounter)
                {
                    //异步处理计数和Redis
                    new Task(() => SysSetCounterRedis(pList)).Start();
                    //异步处理商品评分
                    new Task(() => SysSetProductScore(pList.Select(x => x.ProductId).ToList())).Start();
                    //异步添加买家经验值
                    new Task(() => SysAddUserExp(request.OrderId, request.BuyerId, pList)).Start();
                }
            }
            catch (Exception ex)
            {
                ApplicationLog.Error(
                    string.Format("提交评价Exception  SubmitEvaluate：【{0}】",
                        Newtonsoft.Json.JsonConvert.SerializeObject(request)), ex);
            }
            return result;
        }

        /// <summary>
        /// 判断评价商品一致性
        /// </summary>
        /// <param name="suList"></param>
        /// <param name="pslist"></param>
        /// <returns></returns>
        private bool CheckProductList(List<Ymatou.Evaluate.Buyer.Model.Dto.ProductEvaluate> suList,
            List<EvaluateProdStatus> pslist)
        {
            if (pslist.Count != suList.Count)
            {
                return false;
            }

            //bool flag = true;
            //suList.ForEach(p =>
            //{
            //    if (!pslist.Any(ps => ps.ProductId == p.ProductId && ps.CatalogId == p.CatalogId))
            //    {
            //        flag = false;
            //        return;
            //    }
            //});
            //return flag;
            return suList.All(p => pslist.Any(ps => ps.ProductId == p.ProductId && ps.CatalogId == p.CatalogId));
                }

        /// <summary>
        /// 自动评价
        /// </summary>
        /// <returns></returns>
        public bool AutoEvaluate(AutoEvaluateRequest request)
        {
            var result = false;
            try
            {
                new Task(() => SysAutoEvaluate(request)).Start();
                return true;
            }
            catch (Exception ex)
            {
                ApplicationLog.Error("自动评价Exception  AutoEvaluate", ex);
            }
            return result;
        }

        /// <summary>
        /// 重置评价数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ResetEvaluateResponse ResetEvaluate(ResetEvaluateRequest request)
        {
            var result = new ResetEvaluateResponse();
            try
            {
                //异步重置评价数据
                new Task(() => SysResetEvaluate(request.ProductIds)).Start();
                //异步处理商品评分
                new Task(() => SysSetProductScore(request.ProductIds)).Start();

                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                ApplicationLog.Error("重置评价数据Exception  ResetEvaluate", ex);
            }
            return result;
        }

        private void SysAddUserExp(int orderId, int buyerId, IEnumerable<EvaluateProductImg> pList)
        {
            var orderInfo = GetSellerSingleOrderInfo(orderId, buyerId);
            var hasImgText = pList.Any(p => !string.IsNullOrWhiteSpace(p.OrigComments) || p.HasImgs);
            if (orderInfo != null)
            {
                var totalPrice = orderInfo.RealPaidAmountOfCash + orderInfo.DiscountOfThirdParty -
                                 orderInfo.TotalRefundThirdPartyDiscount;
                AddUserExp(orderId, buyerId, hasImgText.ToString().ToLower(), totalPrice.ToString());
            }
        }

        /// <summary>
        /// 评价完成给买家增加经验值
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="buyerId"></param>
        /// <param name="hasImgText"></param>
        /// <param name="totalPrice"></param>
        private void AddUserExp(int orderId, int buyerId, string hasImgText, string totalPrice)
        {
            var request = new UserExpRequest
            {
                UserId = buyerId,
                BizCode = 100104,
                BizNo = orderId.ToString(),
                ExtParams = new ExtParam
                {

                    HasImgText = hasImgText,
                    IsSubmit = "true",
                    TotalPrice = totalPrice,
                }
            };

            var errorCode = 0;
            var requestParameters = JsonConvert.SerializeObject(request);
            try
            {
                ApplicationLog.Info(string.Format("添加用户经验值请求参数:{0}", requestParameters));
                var response = ServiceClient.Execute<UserExpRequest, UserExpResponse>(request);
                if (response.ErrorCode != 0 && !response.Success)
                {
                    errorCode = response.ErrorCode;
                }
            }
            catch (Exception ex)
            {
                ApplicationLog.Error("添加用户经验值发生异常", ex);
                errorCode = -1;
            }
            finally
            {
                if (errorCode != 0)
                {
                    EvaluateOperatorData.AddUserExpLog(errorCode, requestParameters);
                }
            }
        }

        #region 洗数据用

        /// <summary>
        /// 洗数据用
        /// </summary>
        /// <returns></returns>
        [Obsolete("洗数据用")]
        public void AutoInitEvaluate(AutoSubmitEvaluateRequest request)
        {
            //异步洗数据用
            new Task(() => SysAutoInitEvaluate(request)).Start();
        }

        /// <summary>
        /// 异步洗数据用
        /// </summary>
        /// <returns></returns>
        [Obsolete("洗数据用")]
        private void SysAutoInitEvaluate(AutoSubmitEvaluateRequest data)
        {
            ApplicationLog.Info("异步初始化数据开始");
            var imgs = new List<EvaluateImgs>();
            var list = EvaluateOperatorData.GetBaseEvaluateList(data.OrderIds);
            if (list != null && list.Count > 0)
            {
                list.ForEach(order =>
                {
                    string msg = "";
                    var result = AddEvaluateStatus(order.OrderId, order.SellerId, order.BuyerId, out msg);
                    if (result)
                    {
                        result = EvaluateOperatorData.UpdateBaseEvaluate(order.OrderId, order.BuyerId, order.SellerId,
                            order.AddTime);
                    }
                    if (!result && !string.IsNullOrEmpty(msg))
                    {
                        ApplicationLog.Info(string.Format("异步初始化数据失败，原因：{0}", msg));
                    }
                });
            }
            ApplicationLog.Info("异步初始化数据结束");
        }

        /// <summary>
        /// 洗数据用
        /// </summary>
        /// <returns></returns>
        [Obsolete("洗数据用")]
        public void AutoSubmitEvaluate(AutoSubmitEvaluateRequest request)
        {
            //异步洗数据用
            new Task(() => SysAutoSubmitEvaluate(request)).Start();
        }

        /// <summary>
        /// 异步洗数据用
        /// </summary>
        /// <returns></returns>
        [Obsolete("洗数据用")]
        private void SysAutoSubmitEvaluate(AutoSubmitEvaluateRequest data)
        {
            ApplicationLog.Info("异步洗数据开始");
            var imgs = new List<EvaluateImgs>();
            var list = EvaluateOperatorData.GetSocialComposite(data.OrderIds, out imgs);
            if (list != null)
            {
                var kList = (from p in list
                             group p by new { p.OrderId, p.SellerId, p.BuyerId }
                                 into g
                             select new SubmitEvaluateRequest
                             {
                                 OrderId = g.Key.OrderId,
                                 BuyerId = g.Key.BuyerId,
                                 SellerId = g.Key.SellerId,
                                 LogisticsScore = -1,
                                 ServiceScore = -1
                             }).ToList();

                kList.ForEach(request =>
                {
                    AutoSubmitEvaluate(request,
                        list.Where(
                            p =>
                                p.OrderId == request.OrderId && p.SellerId == request.SellerId &&
                                p.BuyerId == request.BuyerId).ToList(), imgs);
                });
            }
            ApplicationLog.Info("异步洗数据结束");
        }

        /// <summary>
        /// 洗数据
        /// </summary>
        /// <param name="request"></param>
        /// <param name="list"></param>
        /// <param name="imgs"></param>
        [Obsolete("洗数据用")]
        private void AutoSubmitEvaluate(SubmitEvaluateRequest request, List<EvaluateProduct> list,
            List<EvaluateImgs> imgs)
        {
            if (list == null || list.Count <= 0) return;
            //获取订单信息
            var orderProducts = GetSellerSingleOrderInfo(request.OrderId, request.BuyerId);
            if (orderProducts == null || orderProducts.OrderItemList == null || orderProducts.OrderItemList.Count <= 0)
            {
                ApplicationLog.Info(string.Format("异步洗数据，获取不到订单信息，订单号：{0} 买手ID：{1} 买家ID：{2}", request.OrderId,
                    request.SellerId, request.BuyerId));
                return;
            }
            request.ProductsEvaluate = new List<Evaluate.Buyer.Model.Dto.ProductEvaluate>();

            string catalogDesc = "";
            if (list.Count == 1)
                catalogDesc = orderProducts.OrderItemList.FirstOrDefault().PropertyInfo + string.Empty;

            //以订单的数据为主
            orderProducts.OrderItemList.ForEach(x =>
            {
                var product =
                    list.Where(p => p.ProductId == x.ProductId).OrderByDescending(p => p.ProdEvalTime).FirstOrDefault();

                var data = new Evaluate.Buyer.Model.Dto.ProductEvaluate();
                data.CatalogDesc = catalogDesc;
                data.CatalogId = x.CatalogId;
                data.ProductId = x.ProductId;
                data.Score = -1;
                if (product == null)
                {
                    data.Comments = "";
                }
                else
                {
                    data.ProdEvalTime = product.ProdEvalTime;
                    data.Imgs = imgs == null
                        ? null
                        : imgs.Where(img => img.ProdEvalId == product.ProdEvalId).Select(img => img.ImgUrl).ToList();
                    data.Comments = product.Comments;
                    list.Remove(product);
                    if (string.IsNullOrEmpty(data.Comments) && data.Imgs == null)
                        ApplicationLog.Info(string.Format("异步洗数据评价内容为空 笔记内容：{0}", JsonConvert.SerializeObject(product)));
                }
                request.ProductsEvaluate.Add(data);
            });

            string msg = "";
            var response = SubmitEvaluate(request, out msg);
            if (response.IsSuccess)
            {
                //记录成功
                EvaluateOperatorData.UpdateSocialComposite(request.OrderId, request.BuyerId, request.SellerId);
            }
            else
            {
                ApplicationLog.Info(string.Format("异步洗数据结果：失败 原因：{1} 请求Request：{0}",
                    JsonConvert.SerializeObject(request), msg));
            }

        }

        #endregion

        #region 异步处理数据

        /// <summary>
        /// 异步重置评价数据
        /// </summary>
        /// <param name="productIds"></param>
        private void SysResetEvaluate(List<string> productIds)
        {
            if (productIds != null && productIds.Count > 0)
            {
                productIds.ForEach(pid =>
                {
                    int badCounter = 0;
                    int normalCounter = 0;
                    int goodCounter = 0;
                    int picCounter = 0;
                    //读取商品相关评价数据

                    ResetCounter(pid, badCounter, normalCounter, goodCounter, picCounter);
                });
            }
        }

        /// <summary>
        /// 异步自动评价
        /// </summary>
        private void SysAutoEvaluate(AutoEvaluateRequest request)
        {
            ApplicationLog.Info("异步自动评价开始");

            //查询未评价数据
            var list = EvaluateQueryData.GetExpiredEvalOrders();
            if (list != null && list.Count > 0)
            {
                if (request != null && request.OrderIds != null && request.OrderIds.Count > 0)
                {
                    list = list.Where(x => request.OrderIds.Contains(x.OrderId)).ToList();
                }
                if (list != null && list.Count > 0)
                {
                //循环提交评价
                list.ForEach(o =>
                {
                    int orderId = o.OrderId;
                    int buyerId = o.BuyerId;
                    //获取订单信息
                    var orderProducts = GetSellerSingleOrderInfo(orderId, buyerId);
                        if (orderProducts == null || orderProducts.OrderItemList == null ||
                            orderProducts.OrderItemList.Count <= 0) return;
                    //组装评价订单信息
                    var order = new EvaluateOrder();
                    order.LogisticsScore = 5;
                    order.ServiceScore = 5;
                    order.BuyerId = orderProducts.UserId;
                    order.SellerId = orderProducts.BuyerId;
                    order.OrderId = orderProducts.OrderId;
                    order.Way = EvaluateWay.Auto;
                        order.DataType = DataEnum.Normal;
                    //组装评价商品信息
                    var pList = new List<EvaluateProductImg>();
                    orderProducts.OrderItemList.ForEach(x =>
                    {
                        EvaluateProductImg data = new EvaluateProductImg();
                        data.IsSensitive = false;
                            data.Comments = "";
                        data.SellerId = order.SellerId;
                        data.BuyerId = order.BuyerId;
                        data.OrderId = order.OrderId;
                            data.OrigComments = "";
                        data.CatalogDesc = x.PropertyInfo + "";
                        data.CatalogId = x.CatalogId;
                        data.EvaluateTp = EvaluateType.Init;
                        data.HasImgs = false;
                        data.ProductId = x.ProductId;
                        data.ProdEvalTime = DateTime.MinValue;
                        data.Score = 5;
                            order.DataType = DataEnum.Normal;
                        pList.Add(data);
                    });

                    //写入数据库
                    var isSuccess = EvaluateOperatorData.AddEvaluate(order, pList);
                    if (isSuccess)
                    {
                        //异步处理计数和Redis
                        new Task(() => SysSetCounterRedis(pList)).Start();
                        //异步处理商品评分
                        new Task(() => SysSetProductScore(pList.Select(x => x.ProductId).ToList())).Start();
                    }
                        else
                        {
                            ApplicationLog.Info(string.Format("自动评价失败，订单号：【{0}】", orderId));
                        }
                });
            }
            }

            ApplicationLog.Info("异步自动评价结束");
        }

        /// <summary>
        /// 异步处理计数和Redis
        /// </summary>
        /// <param name="data"></param>
        private void SysSetCounterRedis(List<EvaluateProductImg> pList)
        {
            if (pList != null && pList.Count > 0)
            {
                //计数
                SetIncreaseCounter(pList);

                //Redis处理

            }
        }

        /// <summary>
        /// 异步减少评价数
        /// </summary>
        /// <param name="data"></param>
        private void SysSetCounterRedis(EvaluateProduct product)
        {
            if (product != null)
            {
                int scroe = Convert.ToInt32(product.Score);
                List<string> pList = new List<string>() { product.ProductId };
                //减少评价数
                SetDecreaseCounter(scroe, pList);
                //判断是否有图
                if (product.HasImgs)
                {
                    //减少有图评价数
                    SetDecreaseCounter(0, pList);
                }
                //Redis处理

            }
        }

        /// <summary>
        /// 异步处理商品评分
        /// </summary>
        /// <param name="data"></param>
        private void SysSetProductScore(List<string> pList)
        {
            if (pList != null && pList.Count > 0)
            {
                //设置商品评分
                SetProductScore(pList);
            }
        }

        #endregion

        #region 订单查询

        /// <summary>
        /// 订单查询
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="buyerId"></param>
        /// <returns></returns>
        private Ymatou.API.Order.Model.Entities.OrderInfo GetSellerSingleOrderInfo(int orderId, int buyerId)
        {
            var request = new GetSellerSingleOrderInfoRequest();
            request.OrderId = orderId;
            request.UserId = buyerId;
            try
            {
                var response =
                    Ymatou.ServiceCenter.ServiceClient
                        .Execute<GetSellerSingleOrderInfoRequest, BaseResponseModel<GetSingleOrderInfoResponse>>(request);
                ApplicationLog.Info(
                    string.Format(
                        "sellerquery2.trading.iapi.ymatou.com/api/OrderQuery/GetSingleOrderInfo调用订单查询接口：GetSellerSingleOrderInfo()  返回:{0}",
                        JsonConvert.SerializeObject(response)));

                if (response != null && response.RetCode == 200 && response.RetBizCode == 0 && response.RetData != null)
                {
                    return response.RetData.OrderInfo;
                }
            }
            catch (Exception ex)
            {
                ApplicationLog.Info(
                    string.Format(
                        "sellerquery2.trading.iapi.ymatou.com/api/OrderQuery/GetSingleOrderInfo调用订单查询接口：GetSellerSingleOrderInfo()  请求:{0}",
                        JsonConvert.SerializeObject(request)));
                ApplicationLog.Error(
                    "sellerquery2.trading.iapi.ymatou.com/api/OrderQuery/GetSingleOrderInfo调用订单查询接口：GetSellerSingleOrderInfo()",
                    ex);
            }
            return null;
        }

        #endregion

        #region 校验敏感词

        /// <summary>
        /// 校验敏感词
        /// </summary>
        /// <param name="checkStr">需要校验的字符串</param>
        /// <param name="explain">是否显示详情</param>
        /// <param name="banWords">返回的敏感词列表</param>
        /// <returns>是否执行成功</returns>
        bool CheckBanWord(string checkStr, bool explain, out List<string> banWords)
        {
            banWords = new List<string>();
            try
            {
                if (string.IsNullOrEmpty(checkStr)) return false;
                var jsonStr = NetHelper.HttpPost(ServicesApiUrl.AntiSpamServiceUrl, new { sentence = checkStr, biz = "notecomment", explain = explain });
                if (string.IsNullOrEmpty(jsonStr)) return false;
                ApplicationLog.Info(string.Format("敏感词查询接口  返回:{0}", jsonStr));
                var model = JsonConvert.DeserializeObject<CheckBanWordResultEntity>(jsonStr);
                if (model != null && model.status == "OK")
                {
                    //填充返回的敏感词，并去除重复的组合。
                    if (model.hits.Count > 0) //原因：因为这是统一的接口,有些业务是返回多个结果的
                    {
                        foreach (var list in model.hits)
                        {
                            if (!list.spam)
                            {
                                continue;
                            }

                            foreach (var item in list.forbidden)
                            {
                                foreach (var itemsub in item.Value)
                                {
                                    if (!banWords.Contains(itemsub))
                                    {
                                        banWords.Add(itemsub);
                                    }
                                }
                            }
                        }
                    }
                }

                if (banWords == null || banWords.Count <= 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                ApplicationLog.Error("调用敏感词校验异常", ex);
                return false;
            }
        }

        /// <summary>
        /// 评价敏感词处理
        /// </summary>
        /// <param name="checkStr">评价内容</param>
        /// <returns></returns>
        bool GetComments(ref string checkStr)
        {
            var banWords = new List<string>();
            var flag = CheckBanWord(checkStr, false, out banWords);
            if (flag && banWords != null)
            {
                string msg = checkStr;
                banWords.ForEach(x =>
                {
                    msg = msg.Replace(x, "**");
                });
                checkStr = msg;
                return true;
            }
            return false;
        }

        #endregion

        #region 计数服务

        /// <summary>
        /// 设置商品评价分数
        /// </summary>
        /// <param name="pids"></param>
        private void SetProductScore(List<string> pids)
        {
            //读取商品评分
            var data = EvaluateQueryData.GetProductAvgScoreByIds(pids);

            pids.ForEach(pid =>
            {
                int score = 0;
                if (data != null && data.Count > 0)
                {
                    score = Convert.ToInt32(Util.DecimalConvert(data[pid], true));
                }
                AddGroupCounterList(EvaluateConfig.CounterScore, CounterAction.Set, new List<string>() { pid }, score);
            });
        }

        /// <summary>
        /// 重置评价数
        /// </summary>
        /// <param name="pList"></param>
        private void ResetCounter(string productId, int badCounter, int normalCounter, int goodCounter, int picCounter)
        {
            var action = CounterAction.Set;
            //差评
            AddGroupCounterList(EvaluateConfig.CounterBad, action, new List<string>() { productId }, badCounter);
            //中评
            AddGroupCounterList(EvaluateConfig.CounterNormal, action, new List<string>() { productId }, normalCounter);
            //好评
            AddGroupCounterList(EvaluateConfig.CounterGood, action, new List<string>() { productId }, goodCounter);
            //有图
            AddGroupCounterList(EvaluateConfig.CounterPic, action, new List<string>() { productId }, picCounter);
        }

        /// <summary>
        /// 减少评价数
        /// </summary>
        /// <param name="pList"></param>
        private void SetDecreaseCounter(int scroe, List<string> pList)
        {

            switch (scroe)
            {
                //差评
                case 1:
                case 2:
                    AddGroupCounterList(EvaluateConfig.CounterBad, CounterAction.Decrease, pList);
                    break;
                //中评
                case 3:
                    AddGroupCounterList(EvaluateConfig.CounterNormal, CounterAction.Decrease, pList);
                    break;
                //好评
                case 4:
                case 5:
                    AddGroupCounterList(EvaluateConfig.CounterGood, CounterAction.Decrease, pList);
                    break;
                //有图
                default:
                    AddGroupCounterList(EvaluateConfig.CounterPic, CounterAction.Decrease, pList);
                    break;
            }
        }

        /// <summary>
        /// 计数处理
        /// </summary>
        /// <param name="pList"></param>
        private void SetIncreaseCounter(List<EvaluateProductImg> pList)
        {
            if (pList == null || pList.Count <= 0) return;
            //差评
            AddGroupCounterList(EvaluateConfig.CounterBad, CounterAction.Increase,
                pList.Where(x => x.Score >= 0 && x.Score < 3).Select(x => x.ProductId).ToList());
            //中评
            AddGroupCounterList(EvaluateConfig.CounterNormal, CounterAction.Increase,
                pList.Where(x => x.Score == 3).Select(x => x.ProductId).ToList());
            //好评
            AddGroupCounterList(EvaluateConfig.CounterGood, CounterAction.Increase,
                pList.Where(x => x.Score > 3 || x.Score == -1).Select(x => x.ProductId).ToList());
            //有图
            AddGroupCounterList(EvaluateConfig.CounterPic, CounterAction.Increase,
                pList.Where(x => x.HasImgs).Select(x => x.ProductId).ToList());
        }

        /// <summary>
        /// 计数处理
        /// </summary>
        /// <param name="pList"></param>
        private void SetIncreaseCounter(List<EvaluateProduct> pList)
        {
            if (pList == null || pList.Count <= 0) return;
            //差评
            AddGroupCounterList(EvaluateConfig.CounterBad, CounterAction.Increase,
                pList.Where(x => x.Score >= 0 && x.Score < 3).Select(x => x.ProductId).ToList());
            //中评
            AddGroupCounterList(EvaluateConfig.CounterNormal, CounterAction.Increase,
                pList.Where(x => x.Score == 3).Select(x => x.ProductId).ToList());
            //好评
            AddGroupCounterList(EvaluateConfig.CounterGood, CounterAction.Increase,
                pList.Where(x => x.Score > 3 || x.Score == -1).Select(x => x.ProductId).ToList());
            //有图
            AddGroupCounterList(EvaluateConfig.CounterPic, CounterAction.Increase,
                pList.Where(x => x.HasImgs).Select(x => x.ProductId).ToList());
        }

        /// <summary>
        /// 累加计数
        /// </summary>
        /// <param name="counter">好评数:evaluate_good;中评数:evaluate_normal;差评数:evaluate_bad;有图数:evaluate_pic;商品评分:evaluate_score</param>
        /// <param name="targetIds">商品ID列表</param>
        /// <param name="value">默认为1</param>
        /// <returns></returns>
        public Dictionary<string, Dictionary<string, int>> AddGroupCounterList(string counter, CounterAction action, List<string> targetIds, int value = 1)
        {
            if (targetIds == null || targetIds.Count <= 0) return null;

            if (value == 1 && targetIds.Count != targetIds.Distinct().Count())
            {
                var groupList = targetIds.GroupBy(productId => new
                {
                    productId
                }).Select(x => new Ymatou.Evaluate.Buyer.Model.Dto.ProductCounter
                {
                    ProductId = x.Key.productId,
                    Counter = x.Count()
                }).ToList();

                var counterList = groupList.Select(x => x.Counter).Distinct().ToList();

                counterList.ForEach(count =>
                {
                    AddGroupCounterListBase(counter, action, groupList.Where(x => x.Counter == count).Select(x => x.ProductId).ToList(), count);
                });
            }
            else
            {
                AddGroupCounterListBase(counter, action, targetIds, value);
            }
            return null;
        }

        /// <summary>
        /// 调用接口
        /// </summary>
        /// <param name="counter"></param>
        /// <param name="action"></param>
        /// <param name="targetIds"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        Dictionary<string, Dictionary<string, int>> AddGroupCounterListBase(string counter, CounterAction action, List<string> targetIds, int value)
        {
            if (targetIds == null || targetIds.Count <= 0) return null;
            var request = new SetGroupCounterListRequest()
            {
                AppId = EvaluateConfig.CounterAppId,
                Counter = counter,
                TargetIds = targetIds,
                Action = value <= 0 ? CounterAction.Reset : action,
                Value = value
            };
            try
            {
                ApplicationLog.Info(
                    string.Format("api.counter.ymatou.com/api/set/group/list调用计数设置接口：AddGroupCounterList()  请求:{0}",
                        JsonConvert.SerializeObject(request)));
                var response = ServiceClient.Execute<SetGroupCounterListRequest, SetGroupCounterListResponse>(request);
                ApplicationLog.Info(
                    string.Format("api.counter.ymatou.com/api/set/group/list调用计数设置接口：AddGroupCounterList()  返回:{0}",
                        JsonConvert.SerializeObject(response)));
                if (response != null && response.Code == StatusCode.Success)
                {
                    return response.Data;
                }
            }
            catch (Exception ex)
            {
                ApplicationLog.Error("api.counter.ymatou.com/api/set/group/list调用计数设置接口异常：AddGroupCounterList()", ex);
            }
            return null;
        }

        #endregion

        #region 组织数据

        /// <summary>
        /// 组装订单评价信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private EvaluateOrder GetEvaluateOrder(SubmitEvaluateRequest request)
        {
            var order = new EvaluateOrder();
            order.BuyerId = request.BuyerId;
            order.LogisticsScore = request.LogisticsScore;
            order.OrderId = request.OrderId;
            order.SellerId = request.SellerId;
            order.ServiceScore = request.ServiceScore;
            order.Way = EvaluateWay.Buyer;
            order.DataType = DataEnum.Normal;
            return order;
        }

        /// <summary>
        /// 组装商品评价信息
        /// </summary>
        /// <param name="request"></param>
        /// <param name="product"></param>
        /// <returns></returns>
        private EvaluateProductImg GetEvaluateProductImg(SubmitEvaluateRequest request,
            Ymatou.Evaluate.Buyer.Model.Dto.ProductEvaluate product)
        {
            var data = new EvaluateProductImg();
            string comment = product.Comments;
            //敏感词处理
            data.IsSensitive = BanWordUtil.GetComments(ref comment);
            data.Comments = comment;
            data.SellerId = request.SellerId;
            data.BuyerId = request.BuyerId;
            data.OrderId = request.OrderId;
            data.OrigComments = product.Comments;
            data.CatalogDesc = product.CatalogDesc;
            data.CatalogId = product.CatalogId;
            data.EvaluateTp = EvaluateType.Init;
            data.Imgs = product.Imgs;
            data.HasImgs = (product.Imgs != null && product.Imgs.Count > 0);
            data.ProductId = product.ProductId;
            data.Score = product.Score;
            data.ProdEvalTime = (product.ProdEvalTime.HasValue && product.ProdEvalTime.Value != DateTime.MinValue)
                ? product.ProdEvalTime.Value
                : DateTime.MinValue;
            data.DataType = DataEnum.Normal;
            return data;
        }

        public void AutoEvalOrderHis(AutoSubmitEvaluateRequest request)
        {
            new Task(() => SysOrderEvalHis(request)).Start();
        }

        private void SysOrderEvalHis(AutoSubmitEvaluateRequest request)
        {
            var totalCount = EvaluateOperatorData.GetHisEvaluateOrdersCount(request.OrderIds);
            if (totalCount <= 0)
            {
                return;
            }

            var dsrDate = new DateTime(2017, 2, 1, 0, 0, 0);

            var pageCount = (totalCount + request.PageSize - 1) / request.PageSize;
            for (var i = 0; i < pageCount; i++)
            {
                var hisOrders = EvaluateOperatorData.GetHisEvaluateOrders(request.OrderIds, request.PageSize);

                if (hisOrders == null || !hisOrders.Any()) return;

                hisOrders.ForEach(hisOrder =>
                {
                    var orderEvalStatus =
                        EvaluateQueryData.GetOrderStatusByBuyerIdOrderIds(hisOrder.BuyerId,
                            new List<int> { hisOrder.OrderId }).FirstOrDefault();

                    //获取订单信息
                    var orderTradeInfo = GetSellerSingleOrderInfo(hisOrder.OrderId, hisOrder.BuyerId);

                    if (orderEvalStatus == null)
                    {
                        if (orderTradeInfo == null)
                        {
                            //更新历史订单评价同步状态为 IsSync = -100，订单信息不存在
                            EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -100);
                        }
                        else
                        {
                            var orderStatus = new EvaluateOrderStatus
                            {
                                OrderId = hisOrder.OrderId,
                                SellerId = hisOrder.SellerId,
                                BuyerId = hisOrder.BuyerId,
                                AddTime = hisOrder.AddTime,
                                Status = EvaluateStatus.Evaluated,
                                DataType = DataEnum.OrderHisEval,
                            };
                            var orderRes = new EvaluateOrder
                            {
                                OrderId = hisOrder.OrderId,
                                SellerId = hisOrder.SellerId,
                                BuyerId = hisOrder.BuyerId,
                                AddTime = hisOrder.AddTime,
                                DataType = DataEnum.OrderHisEval,
                                Way = EvaluateWay.Buyer,
                                ServiceScore = hisOrder.ServiceScore,
                                LogisticsScore = hisOrder.ServiceScore,
                            };
                            var productState = new List<EvaluateProdStatus>();
                            var products = new List<EvaluateProduct>();

                            //获取订单商品
                            var orderProducts = orderTradeInfo.OrderItemList;
                            if (orderTradeInfo.PaidTime >= dsrDate)
                            {
                                //为避免数据同步导致DSR分数出现大面积异常，此时间节点后的订单中如果商品不存在，也要进入新的交易评价库
                                orderProducts.ForEach(p =>
                                {
                                    productState.Add(new EvaluateProdStatus
                                    {
                                        OrderId = hisOrder.OrderId,
                                        SellerId = hisOrder.SellerId,
                                        BuyerId = hisOrder.BuyerId,
                                        AddTime = hisOrder.AddTime,
                                        ProductId = p.ProductId,
                                        CatalogId = p.CatalogId,
                                        Status = EvaluateStatus.Evaluated,
                                        DataType = DataEnum.OrderHisEval
                                    });

                                    products.Add(new EvaluateProduct
                                    {
                                        OrderId = hisOrder.OrderId,
                                        SellerId = hisOrder.SellerId,
                                        BuyerId = hisOrder.BuyerId,
                                        AddTime = hisOrder.AddTime,
                                        ProductId = p.ProductId,
                                        CatalogId = p.CatalogId,
                                        CatalogDesc =
                                            string.IsNullOrWhiteSpace(p.PropertyInfo) ? string.Empty : p.PropertyInfo,
                                        ProdEvalTime = hisOrder.AddTime,
                                        Score = hisOrder.ServiceScore,
                                        IsSensitive = false,
                                        OrigComments = string.Empty,
                                        Comments = string.Empty,
                                        EvaluateTp = EvaluateType.Init,
                                        IsDeleted = false,
                                        HasImgs = false,
                                        DataType = DataEnum.OrderHisEval
                                    });
                                });
                                if (EvaluateOperatorData.AddOrderEvalHis(orderStatus, productState, orderRes, products))
                                {
                                    SetIncreaseCounter(products);
                                    SetProductScore(products.Select(p => p.ProductId).Distinct().ToList());
                                    //更新历史订单评价同步状态为 IsSync = 1，同步成功
                                    EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, 1);
                                }
                                else
                                {
                                    //更新历史订单评价同步状态为 IsSync = -9，同步失败
                                    EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -1);
                                }
                            }
                            else
                            {
                                //调用商品批量查询接口，获取存在的商品Id
                                var prodIds = orderProducts.Select(p => p.ProductId).Distinct().ToList();
                                var existsProdIds = GetProducts(prodIds);
                                if (existsProdIds != null)
                                {
                                    var existProducts =
                                        orderProducts.Where(p => existsProdIds.Any(ep => ep.Equals(p.ProductId)))
                                            .ToList();
                                    existProducts.ForEach(p =>
                                    {
                                        productState.Add(new EvaluateProdStatus
                                        {
                                            OrderId = hisOrder.OrderId,
                                            SellerId = hisOrder.SellerId,
                                            BuyerId = hisOrder.BuyerId,
                                            AddTime = hisOrder.AddTime,
                                            ProductId = p.ProductId,
                                            CatalogId = p.CatalogId,
                                            Status = EvaluateStatus.Evaluated,
                                            DataType = DataEnum.OrderHisEval
                                        });

                                        products.Add(new EvaluateProduct
                                        {
                                            OrderId = hisOrder.OrderId,
                                            SellerId = hisOrder.SellerId,
                                            BuyerId = hisOrder.BuyerId,
                                            AddTime = hisOrder.AddTime,
                                            ProductId = p.ProductId,
                                            CatalogId = p.CatalogId,
                                            CatalogDesc =
                                                string.IsNullOrWhiteSpace(p.PropertyInfo)
                                                    ? string.Empty
                                                    : p.PropertyInfo,
                                            ProdEvalTime = hisOrder.AddTime,
                                            Score = hisOrder.ServiceScore,
                                            IsSensitive = false,
                                            OrigComments = string.Empty,
                                            Comments = string.Empty,
                                            EvaluateTp = EvaluateType.Init,
                                            IsDeleted = false,
                                            HasImgs = false,
                                            DataType = DataEnum.OrderHisEval
                                        });
                                    });
                                    if (EvaluateOperatorData.AddOrderEvalHis(orderStatus, productState, orderRes,
                                        products))
                                    {
                                        SetIncreaseCounter(products);
                                        SetProductScore(products.Select(p => p.ProductId).Distinct().ToList());
                                        //更新历史订单评价同步状态为 IsSync = 1，同步成功
                                        EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, 1);
                                    }
                                    else
                                    {
                                        //更新历史订单评价同步状态为 IsSync = -9，同步失败
                                        EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -1);
                                    }
                                }
                                else
                                {
                                    //更新历史订单评价同步状态为 IsSync = -101，商品信息不存在
                                    EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -101);
                                }
                            }

                        }
                    }
                    else
                    {
                        if (orderEvalStatus.Status == EvaluateStatus.Evaluated)
                        {
                            List<EvaluateProduct> evaluateProducts;
                            List<EvaluateImgs> evaluateImgs;
                            var evaluateOrder = EvaluateQueryData.GetEvaluateOrder(hisOrder.OrderId, hisOrder.SellerId,
                                hisOrder.BuyerId,
                                out evaluateProducts, out evaluateImgs);
                            if (evaluateOrder.DataType == DataEnum.NoteHis && evaluateOrder.ServiceScore < 0)
                            {
                                //原有笔记数据，更新实际评分
                                if (evaluateProducts != null && evaluateProducts.Any())
                                {
                                    var prodEvalIds = evaluateProducts.Select(p => p.ProdEvalId).ToList();
                                    if (EvaluateOperatorData.UpdateProductEvalNoteScore(hisOrder.OrderId,
                                        hisOrder.SellerId,
                                        hisOrder.BuyerId, prodEvalIds, hisOrder.ServiceScore))
                                    {
                                        try
                                        {
                                            evaluateProducts.ForEach(ep =>
                                            {
                                                SetProductScore(new List<string> { ep.ProductId });
                                                if (hisOrder.ServiceScore <= 3)
                                                {
                                                    if (hisOrder.ServiceScore == 3)
                                                    {
                                                        AddGroupCounterList(EvaluateConfig.CounterNormal,
                                                            CounterAction.Increase, new List<string> { ep.ProductId });
                                                    }
                                                    else
                                                    {
                                                        AddGroupCounterList(EvaluateConfig.CounterBad,
                                                            CounterAction.Increase, new List<string> { ep.ProductId });
                                                    }
                                                    AddGroupCounterList(EvaluateConfig.CounterGood,
                                                        CounterAction.Decrease, new List<string> { ep.ProductId });
                                                }
                                            });
                                            EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, 1);
                                        }
                                        catch (Exception ex)
                                        {
                                            ApplicationLog.Error(string.Format("更新笔记商品计数失败:{0}", ex.Message), ex);
                                            //更新历史订单评价同步状态为 IsSync = -302，更新笔记商品计数失败
                                            EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -302);
                                        }
                                    }
                                    else
                                    {
                                        //更新历史订单评价同步状态为 IsSync = -301，更新笔记评分失败
                                        EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -301);
                                    }
                                }
                                else
                                {
                                    //更新历史订单评价同步状态为 IsSync = -300，笔记评价无数据
                                    EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -300);
                                }
                            }
                            else
                            {
                                //更新历史订单评价同步状态为 IsSync = -200，订单买家已主动评价
                                EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -200);
                            }
                        }
                        else
                        {
                            var prodstatus = EvaluateQueryData.GetProdStatusBySellerIdBuyerIdOrderId(hisOrder.SellerId,
                                hisOrder.BuyerId,
                                hisOrder.OrderId);
                            var prodRes = prodstatus.Select(p => new EvaluateProductImg
                            {
                                AddTime = hisOrder.AddTime,
                                BuyerId = hisOrder.BuyerId,
                                CatalogId = p.CatalogId,
                                Comments = string.Empty,
                                DataType = DataEnum.OrderHisEval,
                                EvaluateTp = EvaluateType.Init,
                                HasImgs = false,
                                Imgs = null,
                                IsDeleted = false,
                                Score = hisOrder.ServiceScore,
                                IsSensitive = false,
                                OrigComments = string.Empty,
                                ProdEvalTime = hisOrder.AddTime,
                                ProductId = p.ProductId,
                            }).ToList();
                            prodRes.ForEach(p =>
                            {
                                if (orderTradeInfo != null && orderTradeInfo.OrderItemList != null &&
                                    orderTradeInfo.OrderItemList.Any())
                                {
                                    var productitem =
                                        orderTradeInfo.OrderItemList.FirstOrDefault(
                                            op => op.ProductId.Equals(p.ProductId) && op.CatalogId.Equals(p.CatalogId));
                                    if (productitem != null)
                                    {
                                        p.CatalogDesc = string.IsNullOrWhiteSpace(productitem.PropertyInfo)
                                            ? string.Empty
                                            : productitem.PropertyInfo;
                                    }
                                    else
                                    {
                                        p.CatalogDesc = string.Empty;
                                    }
                                }
                            });

                            if (EvaluateOperatorData.AddEvaluate(new EvaluateOrder
                            {
                                OrderId = hisOrder.OrderId,
                                SellerId = hisOrder.SellerId,
                                BuyerId = hisOrder.BuyerId,
                                AddTime = hisOrder.AddTime,
                                DataType = DataEnum.OrderHisEval,
                                Way = EvaluateWay.Buyer,
                                ServiceScore = hisOrder.ServiceScore,
                                LogisticsScore = hisOrder.ServiceScore,
                            }, prodRes))
                            {
                                //更新历史订单评价同步状态为 IsSync = 1，同步成功
                                SetIncreaseCounter(prodRes);
                                SetProductScore(prodRes.Select(p => p.ProductId).Distinct().ToList());
                                EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, 1);
                            }
                            else
                            {
                                //更新历史订单评价同步状态为 IsSync = -9，同步失败
                                EvaluateOperatorData.UpdateOrderEvalHis(hisOrder.OrderId, -1);
                            }
                        }
                    }
                });
            }
        }


        private static List<string> GetProducts(List<string> prodIds)
        {
            prodIds = prodIds.Distinct().ToList();

            var request = new GetProductDetailListByTradeIsolationRequest
            {
                ProductIdList = prodIds,
                AppId = "bevaluateo.iapi.ymatou.com"
            };

            try
            {
                var response =
                    ServiceClient
                        .Execute
                        <GetProductDetailListByTradeIsolationRequest,
                            BaseResponseModel
                                <
                                    ProductQuery.BuyerModel.Response.ListResponse.
                                        GetProductDetailListByProductIdListResponse>>(request);
                if (response == null) return null;
                if (response.RetCode == 200 && response.RetData != null && response.RetData.ProductList != null &&
                    response.RetData.ProductList.Any())
                {
                    return response.RetData.ProductList.Select(p => p.ProductId).ToList();
                }
                return null;
            }
            catch (Exception ex)
            {
                ApplicationLog.Error(
                    string.Format(
                        "调用接口prodlist.iapi.ymatou.com/api/Product/GetProductDetailListByTradeIsolation-异常:{0}",
                        ex.Message), ex);
            }
            return null;
        }

        #endregion
    }
}
